﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using MapLibrary;

namespace MapLibrary
{
    public class MapNode
    {

        private Vector2 position;
        private float rotation;
        private Vector2 scale;

        private string textureAsset;
        private Texture2D texture;

        private int mAlphaValue;

        public static MapNode ConstructDefaultMapNode(string AssetName)
        {
            MapNode tReturn = new MapNode();
            tReturn.Position = new Vector2();
            tReturn.Rotation = 0;
            Vector2 tScale = new Vector2();
            tScale.X = 1.0f;
            tScale.Y = 1.0f;
            tReturn.Scale = tScale;
            tReturn.TextureAsset = AssetName;

            return tReturn;
        }

        public MapNode()
        {
            mAlphaValue = 255;
        }

        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }

        [ContentSerializerIgnore]
        public int Alpha
        {
            get { return mAlphaValue; }
            set { mAlphaValue = value; }
        }

        public float Rotation
        {
            get { return rotation; }
            set { rotation = value; }
        }

        public Vector2 Scale
        {
            get { return scale; }
            set { scale = value; }
        }

        /// <summary>
        /// Get the name of the asset for the texture
        /// of the node.
        /// </summary>
        public string TextureAsset
        {
            get { return textureAsset; }
            set { textureAsset = value; }
        }

        /// <summary>
        /// Returns whether or not the texture of the node
        /// has been loaded.
        /// </summary>
        public bool IsLoaded
        {
            get { return texture != null; }
        }

        [ContentSerializerIgnore]
        public Texture2D Texture
        {
            get { return texture; }
        }

        /// <summary>
        /// Get the width of the node.
        /// </summary>
        public int Width
        {
            get { return texture.Width; }
        }

        /// <summary>
        /// Get the center of the node.
        /// </summary>
        public Vector2 Center
        {
            get { return new Vector2(texture.Width / 2, texture.Height / 2); }
        }

        /// <summary>
        /// Get the height of the node.
        /// </summary>
        public int Height
        {
            get { return texture.Height; }
        }

        /// <summary>
        /// Load the texture for the node.
        /// </summary>
        /// <param name="content"></param>
        public void Load(ContentManager content)
        {
            texture = content.Load<Texture2D>(textureAsset);
        }

        /// <summary>
        /// Draw the Node onto the given SpriteBatch.
        /// </summary>
        /// <param name="batch"></param>
        /// <param name="Viewport"></param>
        public void Draw(SpriteBatch batch, WorldViewport Viewport)
        {
            bool toDraw = false;
            if (rotation != 0)
            {
                toDraw = true;
            }
            else{
                Rectangle SpriteRectangle = texture.Bounds;
                SpriteRectangle.X = (int)position.X - texture.Width / 2;
                SpriteRectangle.Y = (int)position.Y - texture.Height / 2;
                toDraw = Viewport.IsRectangleInViewport(SpriteRectangle);
            }
            if (toDraw)
            {
                Vector2 ViewportPos = Viewport.WorldToViewportCoords(position);
                batch.Draw(
                    texture,
                    ViewportPos,
                    null,
                    new Color(255, 255, 255, (byte)mAlphaValue),
                    rotation,
                    this.Center,
                    scale,
                    SpriteEffects.None,
                    0f);
            }
        }
        
    }

    public class MapNodeContentReader : ContentTypeReader<MapNode>
    {
        protected override MapNode Read(ContentReader input, MapNode existingInstance)
        {
            MapNode MapNode = new MapNode();

            MapNode.Position = input.ReadVector2();
            MapNode.Rotation = input.ReadSingle();
            MapNode.Scale = input.ReadVector2();
            MapNode.TextureAsset = input.ReadString();

            MapNode.Load(input.ContentManager);

            return MapNode;
        }
    }

    /// <summary>
    /// This is needed by the SaveManager to properly save the nodes to xml.  Do not
    /// remove this!
    /// </summary>
    [ContentTypeWriter]
    public class MapNodeTypeWriter : ContentTypeWriter<MapNode>
    {
        protected override void Write(ContentWriter output, MapNode value)
        {
            output.Write(value.Position);
            output.Write(value.Rotation);
            output.Write(value.Scale);
            output.Write(value.TextureAsset);
        }

        public override string GetRuntimeReader(TargetPlatform targetPlatform)
        {
            // TODO: change this to the name of your ContentTypeReader
            // class which will be used to load this data.
            return typeof(MapNodeContentReader).AssemblyQualifiedName;
        }
    }
}
